package com.powernode.ssm.springAnalysis.a12.def_JDK.d4;

/**
 * 手写JDK实现动态代理四版：
 * 针对有返回值的bar方法，其调用流程为：
 * 1、main方法new一个$Proxy4的对象，即调用其构造方法public $Proxy4(...)，
 * 此时把lambda表达式逻辑的地址传到$Proxy4的invocationHandler成员变量中
 * 2、main方法走到$Proxy4.bar()方法，执行invocationHandler.invoke()方法
 * 3、接口回调lambda表达式中的逻辑，内部通过反射调用目标类的方法，即bar()方法
 * 4、最后打印
 */
public class D4 {

    interface Foo4 {
        void foo() throws Throwable;
        int bar() throws Throwable;
    }

    static class Target implements Foo4 {
        public void foo() {
            System.out.println("target foo");
        }

        @Override
        public int bar() {
            //5
            System.out.println("target bar");
            return 1;
        }
    }

//jdk已经有了该InvocationHandler接口
//    @FunctionalInterface
//    interface InvocationHandler {
//        Object invoke(Object proxy,Method foo, Object[] objects) throws Throwable;
//    }

    public static void main(String[] param) throws Throwable {
        //把增强逻辑作为参数传入，通过函数式接口InvocationHandler接收
        $Proxy4 $Proxy4 = new $Proxy4((proxy, method, objects) -> {
            //4
            System.out.println("before");
            //反射调用目标方法
            return method.invoke(new Target(), objects);
        });
        //$Proxy4.foo();
        //2
        int bar = $Proxy4.bar();
        //6
        System.out.println("bar = " + bar);

    }
}